import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import Redis from 'ioredis';
import { LoggingService } from '@/services/logging.service';

@Injectable()
export class RedisService implements OnModuleInit, OnModuleDestroy {
    private redis: Redis;

    constructor(private readonly loggingService: LoggingService) {}

    async onModuleInit() {
        try {
            this.redis = new Redis({
                host: process.env.REDIS_HOST || 'localhost',
                port: parseInt(process.env.REDIS_PORT || '6379'),
                password: process.env.REDIS_PASSWORD || '',
                db: parseInt(process.env.REDIS_DB || '0'),
                maxRetriesPerRequest: 3,
            });

            this.redis.on('connect', () => {
                this.loggingService.app('Redis 连接成功');
            });

            this.redis.on('error', (error) => {
                this.loggingService.app('Redis 连接错误', {
                    error: (error as Error).message,
                });
            });

            this.loggingService.app('Redis 服务初始化完成');
        } catch (error) {
            this.loggingService.app('Redis 服务初始化失败', {
                error: (error as Error).message,
            });
        }
    }

    async onModuleDestroy() {
        if (this.redis) {
            await this.redis.quit();
            this.loggingService.app('Redis 连接已关闭');
        }
    }

    async get(key: string): Promise<any> {
        try {
            const value = await this.redis.get(key);
            return value ? JSON.parse(value) : null;
        } catch (error) {
            this.loggingService.app('Redis 获取数据失败', {
                key,
                error: (error as Error).message,
            });
            return null;
        }
    }

    async set(key: string, value: any, ttl?: number): Promise<void> {
        try {
            const serializedValue = JSON.stringify(value);
            if (ttl) {
                await this.redis.setex(key, ttl, serializedValue);
            } else {
                await this.redis.set(key, serializedValue);
            }
        } catch (error) {
            this.loggingService.app('Redis 设置数据失败', {
                key,
                error: (error as Error).message,
            });
        }
    }

    async del(key: string): Promise<void> {
        try {
            await this.redis.del(key);
        } catch (error) {
            this.loggingService.app('Redis 删除数据失败', {
                key,
                error: (error as Error).message,
            });
        }
    }

    async flushAll(): Promise<void> {
        try {
            await this.redis.flushall();
            this.loggingService.app('Redis 缓存已清空');
        } catch (error) {
            this.loggingService.app('Redis 清空缓存失败', {
                error: (error as Error).message,
            });
        }
    }

    async getStats(): Promise<any> {
        try {
            const info = await this.redis.info();
            const dbsize = await this.redis.dbsize();

            return {
                status: 'connected',
                dbsize,
                info: info.split('\r\n').slice(0, 10), // 只返回前10行信息
                timestamp: new Date().toISOString(),
            };
        } catch (error) {
            this.loggingService.app('Redis 获取统计信息失败', {
                error: (error as Error).message,
            });
            return {
                status: 'error',
                error: (error as Error).message,
                timestamp: new Date().toISOString(),
            };
        }
    }
}
